Workflow Designer
An advantage of creating
applications using workflows is the ability to define the workflow
graphically, which is why WF includes a designer for Visual Studio. By
default, the activities appear in the toolbox, letting a developer drag
and drop them onto the tool’s design surface to create a workflow. The
workflow designer is a convenient way to interact with the workflow
namespace.
Workflows
created with the designer are stored in a file based on XAML, a
declarative XML language used to define objects, their properties,
relationships, and interactions. Upon execution, the runtime engine
takes the XAML workflow and creates workflow instances. While there is
only one XAML-based workflow file, there can be multiple workflow
instances running at any given time.
The designer allows you to model
a Sequential Workflow Console Application or a State Machine Workflow
Console Application. After selecting the appropriate model you need to
add activities by dragging and dropping them from the toolbar. (Note
that the console application contains a sub main method that is used to
start the workflow.)
Workflow Persistence (with WF)
Workflows can be dehydrated
from memory and can later be re-hydrated and re-activated. WF supports
dehydration of the instance state by allowing a workflow instance to be
serialized to a data store, such as SQL Server. The workflow instance
can be restored to the original execution state at any time by
de-serializing the data based on events or messages.
The SqlWorkflowPersistenceService
class in WF is designed to connect workflows with SQL Server. In order
to use this persistence service, we need to create a database in SQL
Server with the schema that the persistence service uses. WF comes with
SQL scripts to create the database and schema used by the persistence
service.
The database and schema scripts are typically placed in the following folder after installing WF:
...\Microsoft.NET\Framework\v3.0\Windows Workflow Foundation\SQL
The scripts provided by WF are SqlPersistenceService_Schema.sql and SqlPersistenceService_Logic.sql. The former defines the structure of the database and the latter defines the stored procedures.
The following example provides code that creates an instance of SqlWorkflowPersistenceService
and an instance of the workflow runtime. The workflow runtime is used
to generate an instance of Workflow1 by dehydrating it from the
persistence database. The runtime starts the instance and the instance
ID is stored in the ID property for later use. Finally, the workflow
runtime stops and the state is de-serialized back to the database.
Example 1.
void Load() { WorkflowRuntime workflowRuntime = new WorkflowRuntime(); SqlWorkflowPersistenceService sqlPersistenceService = new SqlWorkflowPersistenceService(this.connectionString); workflowRuntime.AddService(sqlPersistenceService); workflowRuntime.StartRuntime(); WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof (WFWorkflow.CalcWorkflow)); this.id = instance.InstanceId; instance.Load(); instance.Start(); workflowRuntime.StopRuntime(); }
|
WF
includes a tracking service that allows a developer to save information
about a workflow’s execution to the database. For example, the start
date, time and end date, time of a workflow and its activities can be
saved to the database.
Communicating with the Host Container
The base WF library includes the CallExternalMethod and HandleExternalEvent activities used for communication with the host based on the request-response message exchange pattern.
Persisting workflow logic via a database is a classic application of State Repository as a result of the application of the Service Statelessness principle to the task or controller service that resides within WF runtime environment.
|
The WF has a built-in CallExternalMethod
activity, which can raise an event to be consumed by the host. The host
application needs to implement an event handler for receiving response
arguments from the workflow using a standard event-or-delegate pattern. The activity can also be used to send data from the workflow to the host. The HandleExternalEvent is used by the workflow instance to capture an event raised by the host application.
It is critical for the
interface outside the runtime execution context to communicate with the
code in the host application process. The barrier is bridged using a
service designed in the runtime environment called the ExternalDataExchangeService.
This service allows you to make calls into a running workflow instance
using events, and to call out from a running workflow using method
calls. In order to hook up the workflow to the host service, it must
contain a class that implements the interface that is intended for
communications. This interface will use the ExternalDataExchange
attribute to signal the workflow designer and runtime that this
interface is intended for communication between the host and workflow.
Once all these code artifacts are defined, the CallExternalMethod and HandleExternalEvent activities can be hooked up to the host service using the WF designer.